<?php
declare(strict_types=1);

namespace App\Service\Pushapp;
use Exception;
use Hyperf\Guzzle\ClientFactory;
use Psr\Log\LoggerInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
/**
 * 华为推送
 */
class HuaweiService
{
	protected ClientFactory $clientFactory;

    protected LoggerInterface $logger;

    protected $redis;

    private $access_token;

    private $send_url;

    private $base_url;

    private $app_pkgname;

    public function __construct(ClientFactory $clientFactory,LoggerFactory $loggerFactory)
    {
        $this->clientFactory = $clientFactory;
        $this->logger = $loggerFactory->get('log', 'default');
        $container = ApplicationContext::getContainer();
        $this->redis = $container->get(\Hyperf\Redis\Redis::class);
        $config = config('params.huawei', []);
        $this->app_pkgname = $config['appPkgName'];
        $this->base_url = 'https://push-api.cloud.huawei.com/';
        $this->send_url = 'v1/'.$config['clientId'].'/messages:send';
        $this->access_token = $this->getAccessToken($config['clientId'],$config['clientSecret'],$config['tokenCacheKey']);

    }
    /**
     * [getAccessToken 获取华为access token]
     * @param  [type] $clientId     [description]
     * @param  [type] $clientSecret [description]
     * @return [type]               [description]
     */
    public function getAccessToken($clientId,$clientSecret,$tokenCacheKey)
    {
        try {
            //缓存key
            if ($this->redis->exists($tokenCacheKey)) {
                $access_token = $this->redis->get($tokenCacheKey);
            } else {
                $options = [
                    'base_uri' => 'https://oauth-login.cloud.huawei.com/',
                    'timeout'  => 3.0,
                ];
                $post_guz = [
                	'form_params'=>[
						'grant_type'=>'client_credentials',
						'client_id'=>$clientId,
						'client_secret'=>$clientSecret
                	]
                ];
                $resp = $this->clientFactory->create($options)->request('post','oauth2/v3/token',$post_guz);
                $result_body = $resp->getBody()->getContents();
                $result_json = json_decode($result_body,true);
                $access_token = $result_json['access_token'];
                $this->redis->set($tokenCacheKey, $access_token, $result_json['expires_in']);
            }
        } catch (Exception $e) {
            $this->logger->info($e->getMessage() . ' file=' . $e->getFile() . ' line=' . $e->getLine());
            $access_token='';
        }
        return $access_token;
    }

    /**
     * @param array $push_data
     * @param string $reg_id
     * @return false|mixed
     */
    public function sPush(array $push_data, string $reg_id)
    {   
        try {
        	$intent = '';
        	if (isset($push_data['extra']) && !empty($push_data['extra'])) {
        		$intent = 'intent://'.$this->app_pkgname.'/hwpushxhqassistant?#Intent;scheme=hwxhqscheme;launchFlags=0x04000000;S.pushExtra='.json_encode($push_data['extra']).';end';
        	}
        	$sendData = [
        		'validate_only'=>false,
        		'message'=>[
        			'android'=>[
        				'notification'=>[
        					'title'=>$push_data['title'],
        					'body'=>$push_data['content'],
        					'click_action'=>[
        						'type'=>1,
        						'intent'=>$intent
        					],
        				]
        			],
        			'token'=>[$reg_id]
        		],
        	];
			$options = [
			    'base_uri' => $this->base_url,
			    'timeout'  => 3.0,
			];
			$post_guz = [
			    'headers' => ['Content-Type' => 'application/json','Authorization'=>'Bearer '.$this->access_token],
			    'body' => json_encode($sendData)
			];
			$resp = $this->clientFactory->create($options)->request('post', $this->send_url,$post_guz);
			$result_body = $resp->getBody()->getContents();
			$res = json_decode($result_body,true);
			if(!empty($res) && $res['code']=='80000000'){
				return ['status'=>1,'data'=>$res];
			}else{
				return ['status'=>0,'data'=>$res];
			}

        } catch (Exception $e){
            $this->logger->info($e->getMessage());
            return ['status'=>0,'data'=>$e->getMessage()];
        }
    }
}